#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#ifndef __USE_POSIX
#define __USE_POSIX
#endif
#include<sys/wait.h>
#include<signal.h>


void waitchild(int signo){
    pid_t pid;
    while(1){
       pid =waitpid(-1,NULL,WNOHANG);
    if(pid>0){
        printf("child quit is pid =%d\n",pid);
    }else if(pid==0){
        printf("child is living ,pid= %d\n",pid);
        break;
    }else if(pid==-1){
        printf("no child is living pid =%d\n",pid);
        break;
    }else{
        printf(".");

    }
    }
    printf("处理结束\n");
}

int main(){
    int i;
    pid_t pid_init = getpid();
    pid_t pid;
    sigset_t mask;
    sigemptyset(&mask);
    sigaddset(&mask,SIGCHLD);
    sigprocmask(SIG_BLOCK,&mask,NULL);


    for(i=0;i!=3;++i){
        if(getpid()==pid_init){
            pid= fork();

        }
        if(pid<0){
            perror("fork error\n");
            return -1;
        }
        if(pid>0){
            printf("father process, pid=%d ,child pid= %d \n",getpid(),pid);
        }else{
            printf("child process pid= %d, father process pid= %d \n",getpid(),getppid());
            break;
        }
    }    
        if(i==0){

            printf(" the frist child ,pid =%d\n",getpid());
        }
        if(i==1){
     
            printf(" the second child ,pid =%d\n",getpid());
        }
        if(i==2){
        
            printf(" the third child ,pid =%d\n",getpid());
        }
        if(i==3){
            
            struct sigaction act;
            act.sa_handler = waitchild;
            act.sa_flags=0;
            sigemptyset(&act.sa_mask);
            sigaction(SIGCHLD,&act,0);
             // 信号捕获时不阻塞其他信号；
            sleep(5);
            sigprocmask(SIG_UNBLOCK,&mask,NULL);
            printf("the father,pid=%d\n",getpid());
            sleep(10);
            // while(waitpid(-1,NULL,0));
        }
        // 上面的代码是通过让子进程 sleep 1秒 避免让子进程先退出；
}